package cn.exrick.manager.service.impl;


import cn.exrick.common.constant.CommonConstant;
import cn.exrick.common.exception.XmallException;
import cn.exrick.common.pojo.DataTablesResult;
import cn.exrick.common.utils.ThreadPoolUtil;
import cn.exrick.manager.dto.OrderChartData;
import cn.exrick.manager.dto.OrderDetail;
import cn.exrick.manager.dto.OrderRanking;
import cn.exrick.manager.mapper.TbItemMapper;
import cn.exrick.manager.mapper.TbOrderItemMapper;
import cn.exrick.manager.mapper.TbOrderMapper;
import cn.exrick.manager.mapper.TbOrganizationMapper;
import cn.exrick.manager.pojo.*;
import cn.exrick.manager.service.*;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private TbOrderMapper tbOrderMapper;
    @Autowired
    private TbOrderItemMapper tbOrderItemMapper;
    @Autowired
    private UserService userService;
    @Autowired
    private OrganizationService organizationService;
    @Autowired
    private TbItemMapper tbItemMapper;
    @Autowired
    private TbOrganizationMapper tbOrganizationMapper;
    @Autowired
    private EmailTemplateService emailTemplateService;
    @Autowired
    private SysSettingService sysSettingService;

    @Value("${IMAGE_ACCESS_URL}")
    private String imageUrl;

    @Override
    public DataTablesResult getOrderList(int draw, int start, int length, TbOrder tbOrder, String orderCol, String orderDir) {

        DataTablesResult result=new DataTablesResult();
        //分页
        PageHelper.startPage(start/length+1,length);
        List<TbOrder> list = tbOrderMapper.selectByMulti(tbOrder,orderCol,orderDir);
        PageInfo<TbOrder> pageInfo=new PageInfo<>(list);

        result.setRecordsFiltered((int)pageInfo.getTotal());
        result.setRecordsTotal((int)pageInfo.getTotal());

        result.setDraw(draw);
        result.setData(list);
        return result;
    }

    @Override
    public Long countOrder(TbOrder tbOrder) {
        Long result=tbOrderMapper.countOrder(tbOrder);
        return result;
    }

    @Override
    public OrderDetail getOrderDetail(String orderId) {

        OrderDetail orderDetail = new OrderDetail();
        TbOrder tbOrder = tbOrderMapper.selectByPrimaryKey(orderId);

        List<TbOrderItem> orderItemList = tbOrderItemMapper.getOrderItemDatail(orderId);
        for(TbOrderItem orderItem : orderItemList){
            orderItem.setPicPath(imageUrl + orderItem.getPicPath());
        }

        orderDetail.setTbOrder(tbOrder);
        orderDetail.setTbOrderItem(orderItemList);
        return orderDetail;
    }

    @Override
    public int deliver(String orderId,String status) {

        TbOrder o = tbOrderMapper.selectByPrimaryKey(orderId);
        o.setUpdateTime(new Date());
        if("PART".equals(status)){
            o.setStatus(CommonConstant.ORDER_STATUS_PART_DELIVER);
        }else{
            o.setStatus(CommonConstant.ORDER_STATUS_FINISH);
            o.setFinishTime(new Date());
        }

        tbOrderMapper.updateByPrimaryKey(o);
        return 1;
    }

    @Override
    public int remark(String orderId, String message) {
        TbOrder tbOrder = new TbOrder();
        tbOrder.setOrderId(orderId);
        tbOrder.setRemark(message);
        tbOrder.setUpdateTime(new Date());
        tbOrderMapper.updateByPrimaryKeySelective(tbOrder);
        return 1;
    }

    @Override
    public int cancelOrderByAdmin(String orderId) {

        TbOrder o = tbOrderMapper.selectByPrimaryKey(orderId);
        o.setFinishTime(new Date());
        o.setUpdateTime(new Date());
        o.setStatus(CommonConstant.ORDER_STATUS_CANCEL);
        tbOrderMapper.updateByPrimaryKey(o);
        return 1;
    }

    @Override
    public int deleteOrder(String id) {

        if(tbOrderMapper.deleteByPrimaryKey(id)!=1){
            throw new XmallException("删除订单数失败");
        }

        TbOrderItemExample example=new TbOrderItemExample();
        TbOrderItemExample.Criteria criteria= example.createCriteria();
        criteria.andOrderIdEqualTo(id);
        List<TbOrderItem> list =tbOrderItemMapper.selectByExample(example);
        for(TbOrderItem tbOrderItem:list){
            if(tbOrderItemMapper.deleteByPrimaryKey(tbOrderItem.getId())!=1){
                throw new XmallException("删除订单商品失败");
            }
        }

        return 1;
    }

    @Override
    public int invalidOrder(String id) {
        TbOrder tbOrder = tbOrderMapper.selectByPrimaryKey(id);
        if(tbOrder.getStatus() == CommonConstant.ORDER_STATUS_DELIVER || tbOrder.getStatus() == CommonConstant.ORDER_STATUS_PART_DELIVER){
            tbOrder.setFinishTime(new Date());
        }
        tbOrder.setUpdateTime(new Date());
        tbOrder.setStatus(CommonConstant.ORDER_STATUS_INVALID);
        tbOrderMapper.updateByPrimaryKey(tbOrder);
        //释放库存
        List<TbOrderItem> orderItemList = tbOrderItemMapper.getOrderItemDatail(id);
        for(TbOrderItem tbOrderItem : orderItemList){
            tbItemMapper.addNum(Long.valueOf(tbOrderItem.getItemId()),tbOrderItem.getNum());
        }
        return 1;
    }

    @Override
    public int cancelOrder() {

        TbOrderExample example=new TbOrderExample();
        TbOrderExample.Criteria criteria = example.createCriteria();
        criteria.andStatusEqualTo(CommonConstant.ORDER_STATUS_PAYING);
        List<TbOrder> list=tbOrderMapper.selectByExample(example);
        for(TbOrder tbOrder:list){
            judgeOrder(tbOrder);
        }
        return 1;
    }

    @Override
    public void approvalOrder(String orderId,int roleId, int flag) {
        TbOrder o = tbOrderMapper.selectByPrimaryKey(orderId);
        o.setFinishTime(new Date());
        o.setUpdateTime(new Date());
        if(flag == 1){
            if(roleId == CommonConstant.ROLE_ORG_CHARGE){  //部门负责人审核
                o.setStatus(CommonConstant.ORDER_STATUS_ADMIN_APPROVAL);
                //发送管理员审批通知
                ThreadPoolUtil.getPool().execute(()-> emailTemplateService.sendOrderApprovalEmail(orderId,1));
            }else {  //管理员审核
                o.setStatus(CommonConstant.ORDER_STATUS_DELIVER);
                o.setPayTime(new Date());
                //扣除部门余额
                TbUser user = userService.getUserById(o.getUserId());
                TbOrganization organization = organizationService.getOrganizationById(user.getOrganizationId());
                organizationService.updateOrganizationBalance(organization.getId(),organization.getBalance().subtract(o.getPayBalance()));
                //更新库存
                List<TbOrderItem> orderItemList = tbOrderItemMapper.getOrderItemDatail(orderId);
                for(TbOrderItem tbOrderItem : orderItemList){
                    tbItemMapper.reduceNum(Long.valueOf(tbOrderItem.getItemId()),tbOrderItem.getNum());
                }
                //发送取货通知
                ThreadPoolUtil.getPool().execute(()-> emailTemplateService.sendPickupEmail(orderId));
            }

        }else{
            o.setStatus(CommonConstant.ORDER_STATUS_PART_REFUSE);
        }
        tbOrderMapper.updateByPrimaryKey(o);
    }

    @Override
    public TbOrder getTbOrderById(String orderId) {
        return tbOrderMapper.selectByPrimaryKey(orderId);
    }

    @Override
    public List<OrderChartData> statisticOrderStatus(String startTime, String endTime) {
        return tbOrderMapper.statisticOrderStatus(startTime,endTime);
    }

    @Override
    public List<OrderChartData> statisticOrderPayType(String startTime, String endTime) {
        return tbOrderMapper.statisticOrderPayType(startTime,endTime);
    }

    @Override
    public List<OrderRanking> salesRanking(String startTime, String endTime) {
        return tbOrderMapper.salesRanking(startTime,endTime);
    }

    @Override
    public List<OrderRanking> orgApplyRanking(String startTime, String endTime) {
        return tbOrderMapper.orgApplyRanking(startTime,endTime);
    }

    @Override
    public List<OrderRanking> salesStatistic(String startTime, String endTime) {
        dealTime(startTime,endTime);
        List<OrderRanking> list = tbOrderMapper.salesStatistic(startTime,endTime);
        List<OrderRanking> result = new ArrayList<>();
        result.addAll(list);
        //补上销量为0的
        Map<Long, OrderRanking> map = list.stream().collect(Collectors.toMap(OrderRanking::getItemId, orderRanking -> orderRanking));
        TbItemExample example = new TbItemExample();
        TbItemExample.Criteria criteria = example.createCriteria();
        criteria.andStatusEqualTo(CommonConstant.ITEM_STATUS_RELAASE);
        criteria.andSaleDateLessThanOrEqualTo(new Date());
        List<TbItem> tbItems = tbItemMapper.selectByExample(example);
        for(TbItem tbItem : tbItems){
            if(map.get(tbItem.getId()) == null){
                OrderRanking orderRanking = new OrderRanking();
                orderRanking.setItemId(tbItem.getId());
                orderRanking.setItemTitle(tbItem.getTitle());
                orderRanking.setSaleNum(0);
                orderRanking.setSaleAmount(new BigDecimal(0));
                result.add(orderRanking);
            }
        }
        return result;
    }

    private void dealTime(String startTime,String endTime){
        if(StringUtils.isNotBlank(startTime)){
            startTime = startTime + " 00:00:00";
        }
        if(StringUtils.isNotBlank(endTime)){
            endTime = endTime + " 23:59:59";
        }
    }


    @Override
    public List<OrderRanking> orgApplyStatistic(String startTime, String endTime) {
        dealTime(startTime,endTime);
        List<OrderRanking> list = tbOrderMapper.orgApplyStatistic(startTime,endTime);
        List<OrderRanking> result = new ArrayList<>();
        result.addAll(list);
        //补上申领为0的
        Map<Long, OrderRanking> map = list.stream().collect(Collectors.toMap(OrderRanking::getOrganizationId, orderRanking -> orderRanking));
        TbOrganizationExample example = new TbOrganizationExample();
        TbOrganizationExample.Criteria criteria = example.createCriteria();
        criteria.andIsParentEqualTo((byte) 0);
        List<TbOrganization> tbOrganizations = tbOrganizationMapper.selectByExample(example);
        for(TbOrganization tbOrganization : tbOrganizations){
            if(map.get(tbOrganization.getId()) == null){
                OrderRanking orderRanking = new OrderRanking();
                orderRanking.setOrganizationId(tbOrganization.getId());
                orderRanking.setOrganizationName(tbOrganization.getName());
                orderRanking.setApplyNum(0);
                orderRanking.setApplyAmount(new BigDecimal(0));
                result.add(orderRanking);
            }
        }
        return result;
    }

    @Override
    public List<OrderRanking> userApplyStatistic(String startTime, String endTime) {
        dealTime(startTime,endTime);
        return tbOrderMapper.userApplyStatistic(startTime,endTime);
    }

    /**
     * 判断订单是否超时未支付
     */
    public String judgeOrder(TbOrder tbOrder){

        String result=null;
        if(tbOrder.getStatus()==CommonConstant.ORDER_STATUS_PAYING){
            //判断是否已超1小时
            long diff=System.currentTimeMillis()-tbOrder.getCreateTime().getTime();
            long hours = diff / (1000 * 60 * 60);
            if(hours>=1){
                //自动取消
                tbOrder.setStatus(CommonConstant.ORDER_STATUS_CANCEL);
                tbOrder.setFinishTime(new Date());
                tbOrder.setRemark("超时未支付");
                if(tbOrderMapper.updateByPrimaryKey(tbOrder)!=1){
                    throw new XmallException("订单取消失败");
                }
            }else {
                //返回到期时间
                long time=tbOrder.getCreateTime().getTime()+1000 * 60 * 60;
                result= String.valueOf(time);
            }
        }
        return result;
    }

    @Override
    public void finishOrder() {
        TbOrderExample example=new TbOrderExample();
        TbOrderExample.Criteria criteria = example.createCriteria();
        criteria.andStatusEqualTo(CommonConstant.ORDER_STATUS_DELIVER);
        List<TbOrder> orderList = tbOrderMapper.selectByExample(example);
        TbSysSetting setting = sysSettingService.getSetting();
        for(TbOrder tbOrder : orderList){
            long diff=System.currentTimeMillis()-tbOrder.getPayTime().getTime();
            long days = diff / (1000 * 60 * 60 * 24);
            if(days >= Long.valueOf(setting.getPickupEffectiveTime())){
                tbOrder.setStatus(CommonConstant.ORDER_STATUS_FINISH);
                tbOrder.setFinishTime(new Date());
                tbOrder.setRemark("超时未取件");
                tbOrderMapper.updateByPrimaryKey(tbOrder);
            }
        }

    }

    @Override
    public void updatePickingDays(String orderId, Integer pickingDays) {
        TbOrder order = new TbOrder();
        order.setOrderId(orderId);
        order.setPickingDays(pickingDays);
        tbOrderMapper.updateByPrimaryKeySelective(order);
    }
}
